package cc.mycraft.pvp;

import java.util.Date;
import java.util.HashMap;
import java.util.Random;

import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;

public class PVPListener implements Listener{
	public static HashMap<Player,Integer> PlayerCombo = new HashMap<Player,Integer>();
	public static HashMap<Player,Long> PlayerKillTime = new HashMap<Player,Long>();
	public static HashMap<Player,Long> PlayerDeadTime = new HashMap<Player,Long>();
	public static HashMap<Player,Integer> Chicken = new HashMap<Player,Integer>();
    public static boolean Building = false;	
	//安全模式检查
	@EventHandler
	public void onPlayerDamaged(EntityDamageEvent e) {
		if(!(e.getEntity() instanceof Player)) {
			return;
		}
		Player p = (Player) e.getEntity();
		if(SafeArea.Gods.get(p)) {
			e.setCancelled(true);
		}
	}
	//击杀检查
	@EventHandler
	public void onPlayerDeath(PlayerDeathEvent e) {
		Player DeadPlayer = e.getEntity();
		if(SafeArea.isInSafeArea(DeadPlayer)) {
			DeadPlayer.sendMessage("§c你在安全区内死亡，这次死亡不会计入KD，击败你的人也不会获得积分，重生自动开启安全模式。");
			return;
		}
		SafeArea.Gods.replace(DeadPlayer,true);
		//检查被击杀的玩家是否已有连杀数，并清零。
		int DeadCombo = 0;
		if(PlayerCombo.containsKey(DeadPlayer)) {
			DeadCombo = PlayerCombo.get(DeadPlayer);
			PlayerCombo.replace(DeadPlayer, 0);
		}
		int Death = PlayerManager.getDeathAmount(DeadPlayer)+1;
		PlayerManager.setDeathAmount(DeadPlayer,Death);
		//检查是不是玩家伤害，不是玩家伤害则直接返回，记录死亡数。
		if(DeadPlayer.getLastDamageCause()==null || !(DeadPlayer.getLastDamageCause() instanceof EntityDamageByEntityEvent)) {
		    return;
		}
		EntityDamageByEntityEvent e2=(EntityDamageByEntityEvent)DeadPlayer.getLastDamageCause();
		Player Killer = null;
		Entity dmger = e2.getDamager();
	    if(dmger instanceof Arrow) {
	    	Arrow ar = (Arrow) dmger;
	    	Killer = (Player)ar.getShooter();
	    }
	    if(dmger instanceof Player) {
	    	Killer = (Player)dmger;
	    }
	    
		//确认不是自杀，如果是自杀，不记录分数和成就。如果自杀的是菜鸡，不掉分。
		if(Killer.equals(DeadPlayer)) {
			if(Chicken.get(DeadPlayer)>=3) {
				Killer.sendMessage("§c你被自己的武器反噬，使用自伤类武器一定要节制！噢，算了，咯咯哒~");
				return;
			}
			Killer.sendMessage("§c你被自己的武器反噬，使用自伤类武器一定要节制！受到自杀惩罚，竞技积分减少20分。");
			PlayerManager.subPoint(Killer, 20);
			return;
		}
		//重置菜鸡计数
		Chicken.replace(Killer, 0);
		//如果杀的是菜鸡
		if(Chicken.get(DeadPlayer)>=3) {
			ComboChicken(Killer, DeadPlayer);
			return;
		}
		DeadPlayer.getLocation().getWorld().dropItem(DeadPlayer.getLocation(), Main.ArenaChest);
		int Kill = PlayerManager.getKillAmount(Killer)+1;
		PlayerManager.setKillAmount(Killer,Kill);
		//连杀判定
		Combo(Killer,DeadCombo,DeadPlayer,Kill);
	}
	private void Combo(Player Killer,int DeadCombo,Player DeadPlayer,int Kill) {
		long now = new Date().getTime();
		PlayerDeadTime.replace(DeadPlayer,now);
		Chicken.replace(DeadPlayer, Chicken.get(DeadPlayer)+1);
		int combo=1;
		//10秒内击杀玩家，则计入连杀,combo+1
		if(now - PlayerKillTime.get(Killer) < 10000) {
			combo = PlayerCombo.get(Killer)+1;
		}
		//如果不是连杀,则combo=1，重置计数器和时间
		PlayerCombo.replace(Killer, combo);
		PlayerKillTime.replace(Killer, now);
		//连杀获得的额外分数
		int extraPoint = 0;
		//如果终结了玩家
		if(DeadCombo>5) {
			BroadCast("§6§l" + Killer.getName() + "§e终结了§c§l" + DeadPlayer.getName() + "§e！");
		}
		if(DeadCombo>10) {
			DeadCombo=10;
		}
		//更新最高连杀数
		if(combo>PlayerManager.getMaxCombo(Killer)) {
			PlayerManager.setMaxCombo(Killer, combo);
		}
		switch (combo) {
		case 1: break;
		case 2:	extraPoint=1;break;
		case 3:	extraPoint=2;BroadCast("§6§l" + Killer.getName() + "§e已经连胜3人了！");break;
		case 4:	extraPoint=3;BroadCast("§6§l" + Killer.getName() + "§e已经连胜4人！气魄非凡！");break;
		case 5:	extraPoint=4;BroadCast("§6§l" + Killer.getName() + "§e已经连胜5人！势不可挡！");break;
		case 6:	extraPoint=5;BroadCast("§6§l" + Killer.getName() + "§e已经连胜6人！武器大师再临！");break;
		case 7:	extraPoint=6;BroadCast("§6§l" + Killer.getName() + "§e已经连胜7人！横扫千军！");break;
		case 8:	extraPoint=7;BroadCast("§6§l" + Killer.getName() + "§e已经连胜8人！锋芒毕露！");break;
		case 9:	extraPoint=8;BroadCast("§6§l" + Killer.getName() + "§e已经连胜9人！就要接近暴走了！");break;
		case 10:extraPoint=9;BroadCast("§6§l" + Killer.getName() + "§e已经连胜10人！宛如天神下凡！");break;
		default:
			extraPoint=10;BroadCast("§6§l" + Killer.getName() + "§e已经连胜"+combo+"人！战神再世！");break;
		}
		//连杀buff指示，在buff时间内再次击杀玩家，则计一次连杀
		Killer.addPotionEffect(new PotionEffect(PotionEffectType.LUCK, 200, 0, false));
		//三连杀后给强化Buff
		if(combo>=3) {
			Killer.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 60, 0, false));
			Killer.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 100, 1, false));
		}
		Random r = new Random();
		//分数，击杀一人获得基础10分+随机0-5分，连杀数越多，能获得越多的额外分数；被击败的人连杀数越多，也能获得越多的分数，上限为10分，击杀一名玩家可以获得最高35分。
		int addpoint = 10+DeadCombo+extraPoint+r.nextInt(6);
		int point = PlayerManager.getPoint(Killer)+addpoint;
		PlayerManager.setPoint(Killer,point);
		//成就检查
		Achievement.checkKillAchievement(Killer,Kill,combo,point);
		//发送actionbar消息
		ActionBar a = new ActionBar("§6连胜:"+combo+" §6§l击败了 §c"+DeadPlayer.getName()+" §6！   你的竞技场积分：§e§l"+point+"§a(+"+addpoint+")");
		a.send(Killer);
	}
	//杀的是菜鸡，只记录连杀，播放音效。
	private void ComboChicken(Player Killer,Player DeadPlayer) {
		long now = new Date().getTime();
		PlayerDeadTime.replace(DeadPlayer,now);
		Chicken.replace(DeadPlayer, Chicken.get(DeadPlayer)+1);
		int combo=1;
		//10秒内击杀玩家，则计入连杀
		if(now - PlayerKillTime.get(Killer) < 10000) {
			combo = PlayerCombo.get(Killer)+1;
		}
		//如果不是连杀，则重置计数器和时间
		PlayerCombo.replace(Killer, combo);
		PlayerKillTime.replace(Killer, now);
		//更新最高连杀数
		if(combo>PlayerManager.getMaxCombo(Killer)) {
			PlayerManager.setMaxCombo(Killer, combo);
		}
		DeadPlayer.getWorld().playSound(DeadPlayer.getLocation(), Sound.ENTITY_CHICKEN_DEATH, 1, 1f);
		ActionBar a = new ActionBar("§6§l你击败了一只鸡，咯咯哒~");
		a.send(Killer);
	}
	//玩家复活，判断菜鸡并播放音效
	@EventHandler
	public void onPlayerRespawn(PlayerRespawnEvent e) {
		Player p = e.getPlayer();
		if(Chicken.get(p)>=3) {
			p.getWorld().playSound(p.getLocation(), Sound.ENTITY_CHICKEN_AMBIENT, 1, 1f);
			Title chicken = new Title("§6咯咯哒","§e击败你不计战绩，直到你击败一人",5,40,5);
			chicken.send(p);
		}
		Achievement.checkDeathAchievement(p);
	}
	//菜鸡音效
	@EventHandler
	public void onChickenPlayerDamaged(EntityDamageEvent e) {
		if(!(e.getEntity() instanceof Player)) {
			return;
		}
		Player p =(Player) e.getEntity();
		if(Chicken.get(p)>=3) {
			p.getWorld().playSound(p.getLocation(), Sound.ENTITY_CHICKEN_HURT, 1, 1f);
		}
	}
	@EventHandler
	public void onPlayerBuilding(BlockBreakEvent e) {
		if(Building) {
			return;
		}
		e.setCancelled(true);
	}
	@EventHandler
	public void onPlayerBuilding(BlockPlaceEvent e) {
		if(Building) {
			return;
		}
		e.setCancelled(true);
	}
	//玩家加入竞技场服务器时，放入map中。
	@EventHandler
	public static void onPlayerJoinArena(PlayerJoinEvent e) {
		Player p = e.getPlayer();
		PlayerCombo.put(p, 0);
		Chicken.put(p, 0);
		PlayerKillTime.put(p, 0L);
		PlayerDeadTime.put(p, 0L);
		SafeArea.Gods.put(p, true);
	}
	//玩家离开，从所有map中删除。
	@EventHandler
	public void onPlayerQuit(PlayerQuitEvent e) {
		Player p = e.getPlayer();
		SafeArea.Gods.remove(p);
		PlayerCombo.remove(p);
		PlayerKillTime.remove(p);
		PlayerDeadTime.remove(p);
		Chicken.remove(p);
	}
	//这个函数用于插件热重载，热重载后所有map清空，这个函数把玩家加回去避免报错。
	public static void reAddToMap() {
		for(Player p : Bukkit.getServer().getOnlinePlayers()) {
			PlayerCombo.put(p, 0);
			Chicken.put(p, 0);
			PlayerKillTime.put(p, 0L);
			PlayerDeadTime.put(p, 0L);
			if(SafeArea.isInSafeArea(p)) {
				SafeArea.Gods.put(p, true);
			} else {
				SafeArea.Gods.put(p, false);
			}
		}
	}
	public static void BroadCast(String msg) {
		for(Player p : Bukkit.getServer().getOnlinePlayers()) {
			p.sendMessage(msg.replace("&", "§"));
		}
	}
}
